use std::{
    collections::BTreeMap,
    path::PathBuf,
    str::FromStr,
    sync::{atomic::AtomicU64, Arc},
    vec,
};

use quic_secs_driver::SecsClient;

use crate::{
    logger::Logger,
    models::{Preference, TransactionTemplate},
    secs::ConnectionOptions,
};

pub(crate) struct QuicConnection {
    /// 标记
    // pub(crate) identity: String,
    pub(crate) sml_path: PathBuf,
    /// 客户端
    pub(crate) client: Option<Arc<SecsClient>>,

    /// 日志
    pub(crate) logger: Option<Logger>,

    pub(crate) configuration: ConnectionOptions,

    pub(crate) preference: Arc<Preference>,

    /// 事务数据
    pub(crate) transactions: Vec<TransactionTemplate>,
}

impl QuicConnection {
    fn new() -> Self {
        Self {
            // identity: String::new(),
            sml_path: PathBuf::new(),
            client: None,
            logger: None,
            configuration: Default::default(),
            preference: Arc::new(Preference::default()),
            transactions: vec![],
        }
    }

    fn new_with_path(path: PathBuf) -> Self {
        Self {
            // identity: String::new(),
            sml_path: path,
            client: None,
            logger: None,
            configuration: Default::default(),
            preference: Arc::new(Preference::default()),
            transactions: vec![],
        }
    }
}

impl Drop for QuicConnection {
    fn drop(&mut self) {
        if let Some(client) = self.client.as_ref() {
            client.shutdown_sync();
        }
    }
}

static GLOBAL_ID: AtomicU64 = AtomicU64::new(0);
pub(crate) static ALL_CONNS: tokio::sync::RwLock<BTreeMap<u64, QuicConnection>> =
    tokio::sync::RwLock::const_new(BTreeMap::new());

// #[tauri::command]
// pub(crate) fn get_global_id() -> u64 {
//     GLOBAL_ID.fetch_add(1, std::sync::atomic::Ordering::Release)
// }

/// 创建连接，返回连接对应的 id
#[tauri::command]
pub(crate) async fn create_connection(path: Option<String>) -> u64 {
    let result = GLOBAL_ID.fetch_add(1, std::sync::atomic::Ordering::Release);
    if let Some(path) = path {
        match PathBuf::from_str(&path) {
            Ok(sml_path) => {
                let mut guard = ALL_CONNS.write().await;
                guard.insert(result, QuicConnection::new_with_path(sml_path));
                return result;
            }
            Err(_) => {}
        }
    }
    let mut guard = ALL_CONNS.write().await;
    guard.insert(result, QuicConnection::new());
    result
}

#[tauri::command]
pub(crate) async fn remove_connection(id: u64) {
    let mut guard = ALL_CONNS.write().await;
    let _ = guard.remove(&id);
}

pub(crate) async fn clear() {
    let mut guard = ALL_CONNS.write().await;
    let _ = guard.clear();
}

// pub(crate) fn check_identity(id: Option<u64>, identity: String) -> Option<String> {
//     let mut is_exists = false;
//     let guard = COONNECTIONS.read();
//     for (key, val) in guard.iter() {
//         if let Some(id_val) = id.as_ref() {
//             if key == id_val {
//                 continue;
//             }
//         }
//         if val.identity == identity {
//             is_exists = true;
//             break;
//         }
//     }
//     if !is_exists {
//         return None;
//     }
//     let mut index = 1;
//     let mut new_val = format!("{identity}({index})");
//     loop {
//         is_exists = false;
//         for (key, val) in guard.iter() {
//             if let Some(id_val) = id.as_ref() {
//                 if key == id_val {
//                     continue;
//                 }
//             }
//             if val.identity == new_val {
//                 is_exists = true;
//                 break;
//             }
//         }
//         if is_exists {
//             index += 1;
//             new_val = format!("{identity}({index})");
//         } else {
//             return Some(new_val);
//         }
//     }
// }
